<?php
/* {
Citru - www.citru.se
See license.txt for copyright and license information.
} */

if(!defined("_CITRU")) {die('This file should not be accessed directly.');}
require_once 'Module.php';

class PictureModule extends Module {
	
	protected $moduleTabs = array("view", "edit", "settings", "permissions");
	protected $moduleName = "PictureModule";
	protected $instanceName;
	protected $dbModule;
	protected $permissions;
	
	/**
	 * Creates a new picture module object
	 *
	 * @param string $instance 				name of the instance
	 * @param string $db_module 			database module to load data from
	 * @param arrau $permissions 			permissions to views
	 * @return void
	 */
	
	function __construct($instance, $db_module, $permissions) {
		$this->instanceName = $instance;
		$this->dbModule = $db_module;
		$this->permissions = $permissions;
	}
	
	/**
	 * Adds the necessary table for picture module
	 *
	 * @return void
	 */
	public function installTables() {
		$params = array(	"table" => 'PictureModule',
							"columns" => array( array('id', 'int(11) NOT NULL auto_increment'),
							 					array('instance', 'text NOT NULL'),
												array('picture', 'text NOT NULL'),
												array('alt', 'text NOT NULL'),
												array('title', 'text NOT NULL'),
												array('link', 'text NOT NULL'),
												array('class', 'text NOT NULL'),
												array('settings', 'text NOT NULL')),
							"primary_key" => 'id');
		if(!$this->dbModule->addTable($params)) {
			throw new Exception('Could not create table for '.$this->moduleName.'.');
		}
		
		// Add global permissions
		$params_perm = array(	'table' => 'Permissions',
        					'set' => array(	'module'=>$this->moduleName,
											'permissions'=>"view=@admin\nedit=@admin\nsettings=@admin\npermissions=@admin"));
        if(!$this->dbModule->insertRow($params_perm)) {
			throw new Exception('Could not create global permissions for '.$this->moduleName.'.');
		}
	}
	
	/**
	 * Returns the content in the picture module instance
	 *
	 * @return string			html for the content
	 */
	public function getView() {
		if($this->permissions['view'] == false) { return ''; }
		
		// Find this instances row in the db and extract the settings to its own array
		if(!$row = $this->findInstanceRow()) { return "<p>Instance not found!</p>"; }
		$settings = $this->parseSettings($row['settings']);
		
		if($settings['customclass'] != '') {
			$return = '<a href="'.$row['link'].'"><img class="'.$settings['customclass'].'" src="upload/img/'.$row['picture'].'" alt="'.$row['alt'].'" title="'.$row['title'].'" /></a>';
		} else {
			$return = '<img src="'.ROOT.'upload/img/'.$row['picture'].'" alt="'.$row['alt'].'" title="'.$row['title'].'" />';	
		}	
		return $return;
	}
	

	/**
	 * Returns the selected tab of the admin view
	 *
	 * @param string $tab 		selected tab
	 * @return string			html for the selected tab
	 */
	protected function getAdminTab($tab="view") {
		switch($tab) {
			case "edit":
				return $this->getEditForm($message);
			case "settings":
				return $this->getSettingsForm();
			case "permissions":
				return $this->getPermissionsForm();
			default:
				return $this->getView();
		}
	}
	
	
	/**
	 * Returns the html for the edit form, where the picture can be changed
	 *
	 * @return string		html for the edit form
	 */
	private function getEditForm() {
		if($this->permissions['edit'] == false) { return ''; }
		
		if($_POST['instance'] == "PictureModule_$this->instanceName" && $_POST['action'] == "edit") {
			if($_POST['new'] == "true") {
				$message = $this->saveFormData(true);
			} else {
				$message = $this->saveFormData(false);
			}
		}
		
		// Get the form data, generate if instance can't be found
		$row = $this->findInstanceRow();
		$settings = $this->parseSettings($row['settings']);
		$new = 'false';
		if(!$row) { 
			$row['picture'] = '';
			$row['alt'] = 'This instance is empty.';
			$new = 'true';
		}
		
		if($settings['haslink'] == 'true') {
			$link = $this->generateForm(array(
				array('fieldset_start', 'legend'=>'Link'),
				array('label', 'for'=>'link', 'text'=>'Links to:', 'class'=>'citru_narrow'),
				array('input_text', 'name'=>'link', 'value'=>$row['link'], 'class'=>'citru_narrow'),
				array('fieldset_end')));
		}
		
		$elements = array(array('form_start', 'enctype'=>'multipart/form-data'),
						  array('hidden_instance'),
						  array('hidden_action', 'value'=>'edit'),
						  array('hidden_new', 'value'=>$new),
						  
						  array('fieldset_start', 'legend'=>'Change picture'),
						  array('custom', 'data'=>'<p>Current picture: '.$row['picture']."</p>\n"),
						  array('label', 'for'=>'imagefile', 'text'=>'New picture:', 'after'=>'<br />'),
						  array('input_file', 'name'=>'imagefile'),
						  array('fieldset_end'),
						  
						  array('fieldset_start', 'legend'=>'Alt-text and caption'),
						  array('label', 'for'=>'alt', 'text'=>'Alternative text, if the picture can\'t be displayed:', 'after'=>'<br/>'),
						  array('input_text', 'name'=>'alt', 'value'=>$row['alt'], 'after'=>'<br />'),
						  array('label', 'for'=>'title', 'text'=>'Caption, when hovering over the picture:', 'after'=>'<br />'),
						  array('input_text', 'name'=>'title', 'value'=>$row['title']),
						  array('fieldset_end', ''=>''),
						
						  array('custom', 'data'=>$class),
						
						  array('custom', 'data'=>$link),
						  
						  array('footer_start'),
						  array('custom', 'data'=>$message),
						  array('submit', 'value'=>'Save', 'icon'=>'save'),
						  array('footer_end'),
						  array('form_end'));

		$form = $this->generateForm($elements);
		return $form;
	}
	
	/**
	 * Returns a form for editing settings
	 *
	 * @param string $message 		a message to display at the end of the form
	 * @return string				html for the settings form
	 */
	private function getSettingsForm($message="") {
		if($this->permissions['settings'] == false) { return ''; }
		
		// Check if settings should be saved first.
		if($_POST['instance'] == "PictureModule_$this->instanceName" && $_POST['action'] == "settings") {
			$message = $this->saveSettings();
		}
		
		$row = $this->findSettingsRow();
		$settings = $this->parseSettings($row['settings']);
		// Set defaults if unset
		if($settings['haslink'] == '') { $settings['haslink'] = 'false'; }
		
		// Format for use in input/checkbox (true --> checked, false --> '')
		$settings['haslink'] = $this->checkboxEncode($settings['haslink']);
		
		$elements = array(array('form_start'),
						  array('hidden_instance'),
						  array('hidden_action', 'value'=>'settings'),
						  array('fieldset_start', 'legend'=>'Link'),
						  array('input_checkbox', 'name'=>'haslink', 'checked'=>$settings['haslink'], 'text'=>'Picture is a link', 'after'=>'<br />'),
						  array('fieldset_end'),
						  array('fieldset_start', 'legend'=>'Custom classes'),
						  array('label', 'text'=>'Custom style classes to apply to this picture.', 'for'=>'customclass', 'after'=>'<br />'),
						  array('input_text', 'name'=>'customclass', 'value'=>$settings['customclass']),
						  array('fieldset_end'),
						  array('footer_start'),
						  array('custom', 'data'=>$message),
						  array('submit', 'value'=>'Save', 'icon'=>'save'),
						  array('footer_end'),
						  array('form_end'));

		$settings_form = $this->generateForm($elements);
		return $settings_form;
	}
	

	/**
	 * Gives a row from the database with the data for an instance
	 *
	 * @return array 			an array of data for an instance
	 */
	private function findInstanceRow() {
		$params = array(	"table" => "PictureModule",
							"columns" => "picture, alt, title, link, class, settings",
							"condition" =>	array(
											array( "instance", "=", $this->instanceName, "" ) ));
		
		$row = $this->dbModule->findFirst($params);
		return $row;
	}
	
	/**
	 * Saves the changes made in the edit form to the database
	 *
	 * @param boolean $new 			true if the instance should be created first
	 * @return string				message of how things went
	 */
	private function saveFormData($new = false) {
		if($new == true) { $this->createDataRow(); }
		
		if($_FILES['imagefile']['error'] != 4) {
			// A picture is uploaded, do some error handling
			if ($_FILES['imagefile']['error'] > 0) {
				return '<p class="citru_error">File error: '.$_FILES['imagefile']['error'].'</p>';
			}
			
			if(preg_match("/(jpeg|jpg|gif|png)/", $_FILES['imagefile']['type']) == 0) {
				return '<p class="citru_error">The image must be of type jpg, gif or png.</p>';
			}
			
			if($_FILES['imagefile']['size'] > 10000000) {
				return '<p class="citru_error">The image must be under 10mb in size.</p>';
			}
			
			$img_number = 0;
			while( file_exists(ROOT."upload/img/".$img_number.'_'.$_FILES["imagefile"]["name"]) ) {
				$img_number++;
				if($img_number > 100) {
					return '<p class="citru_error">The filename already exists in the upload dir.</p>';
				}
			}
			
			if( !move_uploaded_file($_FILES["imagefile"]["tmp_name"], getcwd().'/'.ROOT."upload/img/".$img_number.'_'.$_FILES["imagefile"]["name"]) ) {
				return '<p class="citru_error">File upload failed: upload dir unwritable.</p>';
			}
		
			$picture = $img_number.'_'.$_FILES["imagefile"]["name"];

		} else {
			// No picture was uploaded
			$old_row = $this->findInstanceRow();
			$picture = $old_row['picture'];
		}
		
		$alt = $_POST['alt'];
		$title = $_POST['title'];
		$link = $_POST['link'];
		
		$params = array(	"table" => "PictureModule",
							"condition" =>	array(
											array( "instance", "=", $this->instanceName, "" ) ),
							"set" => array( 	"alt" => $alt,
												"title" => $title,
												"link" => $link,
												"picture" => $picture ));
																	
		$result = $this->dbModule->updateRow($params);
		if($picture == "") return '<p class="citru_warning">Form data saved. No image selected.</p>';
		return '<p class="citru_event">Form data saved.</p>';
	}
	
	/**
	 * Updates the settings of a previous instance from form data
	 *
	 * @return string			message of how things went
	 */
	private function saveSettings() {
		$haslink = $this->checkboxDecode($_POST['haslink']);
		$customclass = $_POST['customclass'];
		
		$settings = 'haslink='.$haslink."\n";
		$settings .= 'customclass='.$customclass."\n";
		
		$params = array(	"table" => "PictureModule",
							"condition" =>	array(array( "instance", "=", $this->instanceName, "" )),
							"set" => array( "settings" => $settings ));
																	
		$result = $this->dbModule->updateRow($params);
		
		return '<p class="citru_event">Settings saved.</p>';
	}
	
}

?>
